Jx.declare('Jx.lib.Configurable', {
	
	$requires: [ 'Jx.lib.Array' ],
	
	$actions: [

		'configure'
		
	],
	
	$cascadeCallback: function(Class, Base){

		var ClassPrototype = Class.prototype,

			BasePrototype = Base.prototype;

		ClassPrototype.configOrder = Jx.lib.Array.unique( ClassPrototype.configOrder, BasePrototype.configOrder, Class.$data.names );

	},
	
	constructor: function(config){
		
		this.$super();
		
		this.configure( config );
		
	},
	
	onConfigure: function(operation, config){

		var data = this.$cache;

		for(var property, value, configurator, hasValue, order = this.configOrder, c=0, l = order.length; c<l; c++){

			property = order[c];

			configurator = 'onConfigure' + property.charAt(0).toUpperCase() + property.substring(1, property.length);

			hasValue = config.hasOwnProperty(property);

			value = hasValue ?

				config[property]

				:

				void(0);

			if (configurator in this && Jx.isFunction(this[configurator])){

				this[configurator](value, config);

			} else if (hasValue){

				data[property] = value;

			}

		}

	},
	
	allowConfigure: function(operation, config){

		return Jx.isObject(config);

	}
	
});
